<?php
/**
 * @author Thibaut Cromphaut, Gaïtano Boeraeve, Mathias Helin, Dimitry Dierickx
 * @copyright  Copyright (c) 2011 Artevelde University College Ghent 
 */

class IndexController extends Zend_Controller_Action
{

    private $_redirector = null;

    private $_readinglist_page_limit = 6;

    private $_courses_page_limit = 10;

    private $_notes_page_limit = 10;

    private $_announces_page_limit = 10;

    public function init()
    {
        $this->_redirector = $this->_helper->getHelper('Redirector');
        $this->stylesBase  = $this->view->baseUrl() . '/styles/';
    }

    /**
     * This will validate our session and the requested action;
     */
    public function preDispatch()
    {
        // Check our identity
        if(Zend_Auth::getInstance()->hasIdentity())
        {
            // Check the requestion action
            switch ( $this->getRequest()->getActionName())
            {
                case 'index':
                case 'deletecourse':
                case 'deletenote':
                case 'ajaxrequest':
                case 'deletebook':
                case 'legal':
                case 'privacy':
                    // -- These actions are allowed, nothing to do -- //
                    break;
                default:
                    // -- Invalid action requested, refer to homepage -- //
                    $this->_helper->redirector('index', 'index');
                    break;
            }
        }
        else
        {
            // We have another layout for welcoming non-authenticated users
            $layout = $this->_helper->layout();
            $layout->setLayout('layout_index'); 
            
            // Check the requestion action
            switch ( $this->getRequest()->getActionName())
            {
                case 'legal':
                case 'privacy':
                    // -- These actions are allowed, nothing to do -- //
                    break;
                default:
                    // -- No session, refer to loginpage -- //
                    $this->_helper->redirector('login', 'user');
            }
        }
    }

    /**
     * This action will handle all ajax-requests
     */
    public function ajaxrequestAction()
    {
        // Disable the layout
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        
        // Get current user
        $user   = Zend_Auth::getInstance()->getStorage()->read();
        
        // These are default pager variables
        $current_page   = (string)$this->getRequest()->getParam('p');
        $pager_base     = $this->getRequest()->getBaseUrl()."/index/index/";
        
        // Get the request and do something accordingly
        $request  = (string)$this->getRequest()->getParam('req');
        switch($request)
        {
            case "pagebooks":
                $pager_var      = "bp";
                $html[]         = $this->_loopPartial('alle-block-readinglist', $this->_getBooksByUserId($user->Id, $current_page, $this->_readinglist_page_limit));
                $html[]         = $this->_fetchPager($current_page, ($this->_countBooksByUserId($user->Id)/$this->_readinglist_page_limit), $pager_base, $pager_var);
                $result         = implode("\n", $html);
                break;
            case "pagecourses":
                $pager_var      = "cp";
                $html[]         = $this->_loopPartial('alle-block-courses', $this->_getCoursesByUserId($user->Id, $current_page, $this->_courses_page_limit));
                $html[]         = $this->_fetchPager($current_page, ($this->_countCoursesByUserId($user->Id)/$this->_courses_page_limit), $pager_base, $pager_var);
                $result         = implode("\n", $html);
                break;
            case "pagenotes":
                $pager_var      = "np";
                $html[]         = $this->_loopPartial('alle-block-notes', $this->_getNotesByAuthorId($user->Id, $current_page, $this->_notes_page_limit));
                $html[]         = $this->_fetchPager($current_page, ($this->_countNotesByAuthorId($user->Id)/$this->_notes_page_limit), $pager_base, $pager_var);
                $result         = implode("\n", $html);
                break;
            case "pageannounoucements":
                $pager_var      = "ap";
                $html[]         = $this->_loopPartial('alle-block-announcements', $this->_getAnnouncementsByUserId($user->Id, $current_page, $this->_announces_page_limit));
                $html[]         = $this->_fetchPager($current_page, ($this->_countAnnouncementsByUserId($user->Id)/$this->_announces_page_limit), $pager_base, $pager_var);
                $result         = implode("\n", $html);
                break;
            default:
                $result = false;
                break;
        }
        
        // output result
        echo $result; 
    }

    /**
     * This is the main action.
     * It will display the My All-E page
     */
    public function indexAction()
    {
        // Set up the view
        $view   = $this->_getView('Home');
        // Get the logged in User-object, and get other 
        $user   = Zend_Auth::getInstance()->getStorage()->read();
        // Pass some variables to our view
        $view->user     = $user;
        // Pager variables
        $pager_base     = $this->getRequest()->getBaseUrl()."/index/index/";
        // Set READINGLIST block
        $book_count         = $this->_countBooksByUserId($user->Id);
        if($book_count > 0)
        {
            $book_pager_var     = "bp";
            $book_current_page  = (string)$this->getRequest()->getParam($book_pager_var);
            $book_current_page  = ($book_current_page > 0 ? $book_current_page : 1);
            $view->book_partial = $this->_loopPartial('alle-block-readinglist', $this->_getBooksByUserId($user->Id, $book_current_page, $this->_readinglist_page_limit));
            $view->book_pager   = $this->_fetchPager($book_current_page, ($book_count/$this->_readinglist_page_limit), $pager_base, $book_pager_var);
        }
        else
        {
            $view->book_partial = $view->partial('partials/add-book.phtml', array());
            $view->book_pager   = null;
        }
        // Set COURSES block
        $crse_count         = $this->_countCoursesByUserId($user->Id);
        if($crse_count > 0)
        {
            $crse_pager_var     = "cp";
            $crse_current_page  = (string)$this->getRequest()->getParam($crse_pager_var);
            $crse_current_page  = ($crse_current_page > 0 ? $crse_current_page : 1);
            $view->crse_partial = $this->_loopPartial('alle-block-courses', $this->_getCoursesByUserId($user->Id, $crse_current_page, $this->_courses_page_limit));
            $view->crse_pager   = $this->_fetchPager($crse_current_page, ($crse_count/$this->_courses_page_limit), $pager_base, $crse_pager_var);
        }
        else
        {
            $view->crse_partial = $view->partial('partials/add-course.phtml', array());
            $view->crse_pager   = null;
        }
        // Set ANNOUNCEEMENTS block
        $annc_count         = $this->_countAnnouncementsByUserId($user->Id);
        if($annc_count > 0)
        {
            $annc_pager_var     = "ap";
            $annc_current_page  = (string)$this->getRequest()->getParam($annc_pager_var);
            $annc_current_page  = ($annc_current_page > 0 ? $annc_current_page : 1);
            $view->annc_partial = $this->_loopPartial('alle-block-announcements', $this->_getAnnouncementsByUserId($user->Id, $annc_current_page, $this->_announces_page_limit));
            $view->annc_pager   = $this->_fetchPager($annc_current_page, ($annc_count/$this->_announces_page_limit), $pager_base, $annc_pager_var);
        }
        else
        {
            if($crse_count > 0)
            {
                $view->annc_partial = "<p>There are currently no accouncements for your courses.</p>";
            }
            else
            {
                $view->annc_partial = "<p>Start subscribing to courses to view announcements.</p>";
            }
            $view->annc_pager   = null;
        }
        // Set NOTES block
        $note_count         = $this->_countNotesByAuthorId($user->Id);
        if($note_count > 0)
        {
            $note_pager_var     = "np";
            $note_current_page  = (string)$this->getRequest()->getParam($note_pager_var);
            $note_current_page  = ($note_current_page > 0 ? $note_current_page : 1);
            $view->note_partial = $this->_loopPartial('alle-block-notes', $this->_getNotesByAuthorId($user->Id, $note_current_page, $this->_notes_page_limit));
            $view->note_pager   = $this->_fetchPager($note_current_page, ($note_count/$this->_notes_page_limit), $pager_base, $note_pager_var);
        }
        else
        {
            if($book_count > 0)
            {
                $view->note_partial = "<p>You have not submitted any notes to a book.</p>";
            }
            else
            {
                $view->note_partial = "<p>Add books to your readinglist and add notes to the articles.</p>";
            }
            $view->note_pager   = null;
        }
    }
    
    /**
     * Display the legal disclaimer
     */
    public function legalAction()
    {
        $view   = $this->_getView("Legal disclaimer");
    }
    
    /**
     * Display the privacy statement
     */
    public function privacyAction()
    {
        $view   = $this->_getView("Privacy statement");
    }

    /**
     * This will let a user delete a course from his readinglist
     */
    public function deletecourseAction()
    {
        $user       = Zend_Auth::getInstance()->getStorage()->read();
        $course_id  = (string)$this->getRequest()->getParam('id');
        $this->_removeCourseFromReadinglist($course_id, $user->Id);
        $this->_helper->redirector('index', 'index'); 
    }

    /**
     * This will let a user delete a book from his readinglist
     */
    public function deletebookAction()
    {
        $user     = Zend_Auth::getInstance()->getStorage()->read();
        $book_id  = (string)$this->getRequest()->getParam('id');
        $this->_removeBookFromReadinglist($book_id, $user->Id);
        $this->_helper->redirector('index', 'index');
    }

    /**
     * This will let a user delete one of his notes
     */
    public function deletenoteAction()
    {
        $user     = Zend_Auth::getInstance()->getStorage()->read();
        $note_id  = (string)$this->getRequest()->getParam('id');
        $this->_removeNote($note_id);
        $this->_helper->redirector('index', 'index');
    }

    /**
     * Get the user's announcements
     *
     * @param integer $user_id
     * @param integer $page_nr      If you wish to use paging, pass the page-number. To
     *                              disable paging, pass null as value (default) and 
     *                              return all rows.
     * @param integer $nr_results   The number of results per page, defaults to 10.
     * @return Array(Application_Model_Announcement)
     */
    private function _getAnnouncementsByUserId($user_id, $page_nr = null, $nr_results = 0)
    {
        $mapper = new Application_Model_AnnouncementMapper();
        return $mapper->fetchByUserId($user_id, $page_nr, $nr_results);
    }

    /**
     * Returns the number of announcements for a user
     *
     * @param integer $user_id
     * @return integer
     */
    private function _countAnnouncementsByUserId($user_id)
    {
        $mapper = new Application_Model_AnnouncementMapper();
        return $mapper->getCountByUserId($user_id);
    }

    /**
     * Get the user's courselist
     *
     * @param integer $user_id
     * @param integer $page_nr      If you wish to use paging, pass the page-number. To
     *                              disable paging, pass null as value (default) and 
     *                              return all rows.
     * @param integer $nr_results   The number of results per page, defaults to 10.
     * @return Array(Application_Model_Course)
     */
    private function _getCoursesByUserId($user_id, $page_nr = null, $nr_results = 0)
    {
        $mapper = new Application_Model_CourseMapper();
        return $mapper->fetchByUserId($user_id, $page_nr, $nr_results);
    }

    /**
     * Returns the number of courses the user is subscribed to
     *
     * @param int $user_id
     * @return int 
     */
    private function _countCoursesByUserId($user_id)
    {
        $mapper = new Application_Model_CourseMapper();
        return $mapper->getCountByUserId($user_id);
    }

    /**
     * Get the user's readinglist
     *
     * @param integer $user_id
     * @param integer $page_nr      If you wish to use paging, pass the page-number. To
     *                              disable paging, pass null as value (default) and 
     *                              return all rows.
     * @param integer $nr_results   The number of results per page, defaults to 10.
     * @return Array(Application_Model_Book)
     */
    private function _getBooksByUserId($user_id, $page_nr = null, $nr_results = 0)
    {
        $mapper = new Application_Model_BookMapper();
        return $mapper->fetchByUserId($user_id, $page_nr, $nr_results);
    }

    /**
     * Returns the number of books the user has in his readinglist
     *
     * @param int $user_id
     * @return int 
     */
    private function _countBooksByUserId($user_id)
    {
        $mapper = new Application_Model_BookMapper();
        return $mapper->getCountByUserId($user_id);
    }

    /**
     * Get the user's notes
     *
     * @param integer $user_id
     * @param integer $page_nr      If you wish to use paging, pass the page-number. To
     *                              disable paging, pass null as value (default) and 
     *                              return all rows.
     * @param integer $nr_results   The number of results per page, defaults to 10.
     * @return Array(Application_Model_Book)
     */
    private function _getNotesByAuthorId($user_id, $page_nr = null, $nr_results = 0)
    {
        $mapper = new Application_Model_CommentMapper();
        return $mapper->fetchByAuthorId($user_id, $page_nr, $nr_results);
    }

    /**
     * Returns the number of notes made by this user
     *
     * @param int $user_id
     * @return int 
     */
    private function _countNotesByAuthorId($user_id)
    {
        $mapper = new Application_Model_CommentMapper();
        return $mapper->getCountByAuthorId($user_id);
    }

    /**
     * Removes a course from the user's readinglist
     *
     * @param integer $course_id
     * @param integer $user_id
     */
    private function _removeCourseFromReadinglist($course_id, $user_id)
    {
        $mapper = new Application_Model_UserMapper();
        $mapper->deleteCourseFromUser($course_id, $user_id);
    }

    /**
     * Removes a book from the user's readinglist
     *
     * @param integer $book_id
     * @param integer $user_id
     */
    private function _removeBookFromReadinglist($book_id, $user_id)
    {
        $mapper = new Application_Model_UserMapper();
        $mapper->deleteBookFromUser($book_id, $user_id);
    }

    /**
     * Removes a note
     *
     * @param integer $note_id
     */
    private function _removeNote($note_id)
    {
        $mapper = new Application_Model_CommentMapper();
        $mapper->delete($note_id);
    }

    /**
     * Loops through a list of custom objects, passing each object to the partial.
     * The end result is a html-render of the all the partials.
     *
     * @param string $partial
     * @param Array $objects
     * @return string
     */
    private function _loopPartial($partial, $objects, $extravars=null)
    {
        $result = array();
        $count  = 0;
        if(count($objects))
        {
            foreach($objects as $object)
            {
                $count++;
                $vars       = array(
                    'object'    => $object,
                    'count'     => $count,
                );
                
                if(is_array($extravars))
                    $vars = array_merge($extravars, $vars);
                
                $result[]   = $this->_getView("")->partial('partials/'.$partial.'.phtml', $vars);
            }
        }
        
        return implode("\n", $result);
    }

    /**
     * Get the HTML pager for a list that requires pagination
     *
     * @param int $page_nr
     * @param int $total_pages
     * @param string $base_url
     * @param string $page_var
     * @return string 
     */
    private function _fetchPager($current_page, $total_pages, $base_url, $page_var)
    {
        $view   = $this->_getView("");
        $vars   = array(
            'cur_page'      => $current_page,
            'nr_of_pages'   => ceil($total_pages),
            'base_url'      => $base_url,
            'page_var'      => $page_var,
        );
        
        return $view->partial('partials/pager.phtml', $vars);
    }

    /**
     * This returns the view for this controller.
     *
     * @param string $title
     * @return Zend_View
     */
    private function _getView($title)
    {
        $view = $this->view;
        $view->title = $title;
        $view->headTitle($view->title, 'PREPEND');

        return $view;
    }
}